/**
 * 
 */
package yartiss.engine.simulation.scheduling.policies.fp;

import java.util.SortedSet;

import yartiss.engine.simulation.Event;
import yartiss.engine.simulation.IEnergyProfile;
import yartiss.engine.simulation.ISchedulingPolicy;
import yartiss.engine.simulation.events.EventGenerator;
import yartiss.engine.simulation.scheduling.policies.AbstractMonoProcessorSchedulingPolicy;
import yartiss.engine.simulation.scheduling.policies.tools.FPSlackEnergyManager;
import yartiss.engine.simulation.system.ITask;
import yartiss.engine.simulation.system.ITaskSet;
import yartiss.engine.simulation.system.taskset.TaskSetFactory;

/**
 * @author dm
 * 
 */
public class EHPFP6SchedulingPolicy extends AbstractMonoProcessorSchedulingPolicy{

	private final FPSlackEnergyManager slackEnergyManager;

	public EHPFP6SchedulingPolicy(FPSlackEnergyManager slackEnergyManager) {

		this.slackEnergyManager = slackEnergyManager;
	}

	@Override
	public String getPolicyName() {
		return "EH_PFP_6";
	}

	@Override
	public ISchedulingPolicy newInstance() {
		return new EHPFP6SchedulingPolicy(new FPSlackEnergyManager());
	}

	@Override
	public ITaskSet createTaskSet() {
		return TaskSetFactory.getNewInstance("priority");
	}


	@Override
	public ITask chooseNextTask(ITaskSet taskSet, IEnergyProfile energyProfile, long date, EventGenerator evGen) {

		metrics.clear();

		SortedSet<ITask> activeTasks = taskSet.getActiveTasks(date);

		if (activeTasks.isEmpty()) {
			return null;
		}

		ITask first = activeTasks.first();

		// si on est a emax
		if((energyProfile.getMaxEnergyLevel()-energyProfile.getCurrentEnergyLevel())/energyProfile.getPowerRate() < 1){
			long hlce = energyProfile.howLongCanExecute(first);
			if(hlce <= 0 )return null;
			if(hlce < first.getRemainingCost())
				evGen.generateEvent("check_energy_state", first, date + hlce, null);
			return first;
		}
		
		//	sinon 
		
		long se = slackEnergyManager.getSlackEnergy(date, taskSet, energyProfile);
		metrics.put(Event.SlackEnergy, se);

		evGen.generateEvent("check_energy_state", first, date + 1, null);
		
		
		if ( energyProfile.howLongCanExecute(se,first) > 0) {	
			return first;
		}
		
		return null;
	}

}
